#include "oled.h"
#include "oledfont.h"
#include "spi.h"

#define OLED_SPI &hspi2

unsigned char OLED_GRAM[144][8];

const char OLED_InitCMD[] =
    {
        39,
        0xAE, 0x15, 0x00, 0x4f, 0x75, 0x00, 0x3f, 0x81,
        0xb0, 0xa0, 0xc1, 0xa1, 0x00, 0xa2, 0x00, 0xa3,
        0x00, 0x40, 0xa4, 0xa8, 0x3f, 0xab, 0x00, 0xad,
        0x8e, 0xb1, 0x82, 0xb3, 0xa0, 0xb6, 0x04, 0xb9,
        0xbc, 0x04, 0xbd, 0x01, 0xbe, 0x05

};
void OLED_WR_Byte(unsigned char dat, unsigned char cmd)
{
    if (cmd)
        OLED_DC_Set();
    else
        OLED_DC_Clr();
    OLED_CS_Clr();
    HAL_SPI_Transmit(OLED_SPI, &dat, 1, 0xff);
    OLED_CS_Set();
    OLED_DC_Set();
}

void OLED_WR_CMD(unsigned char cmd)
{
    OLED_DC_Clr();
    OLED_CS_Clr();
    HAL_SPI_Transmit(OLED_SPI, &cmd, 1, 0xff);
    OLED_CS_Set();
    OLED_DC_Set();
}

void OLED_WR_DAT(unsigned char cmd)
{
    OLED_DC_Set();
    OLED_CS_Clr();
    HAL_SPI_Transmit(OLED_SPI, &cmd, 1, 0xff);
    OLED_CS_Set();
    OLED_DC_Clr();
}

void OLED_WR_DAT_Plent(unsigned char *temp, short len)
{
    OLED_DC_Set();
    OLED_CS_Clr();
    HAL_SPI_Transmit(OLED_SPI, temp, len, 0xff);
    OLED_CS_Set();
    OLED_DC_Clr();
}

void OLED_ShowString(unsigned char x0, unsigned char y0, char *s, unsigned char color, unsigned char B_color)
{
    unsigned char i = 0;
    for (;; i++) {
        if (s[i] == '\n' || s[i] == '\0')
            break;
        else
            General_Pic_Display(x0 + (i * 8), y0, 8, 16, (char *)ASCLL[s[i] - 32], color, B_color);
    }
}
void OLED_ShowNumber(unsigned char x0, unsigned char y0, int num, unsigned char length, unsigned char color, unsigned char bcolor)
{
    char str[length + 1];
    unsigned char i;
    int temp;

    // 将数字按位拆分存储到字符串中
    for (i = 0; i < length; i++) {
        temp                = num % 10;
        str[length - i - 1] = temp + '0';
        num /= 10;
    }
    str[length] = 0;

    OLED_ShowString(x0, y0, (char *)str, color, bcolor);
}

void OLED_FillArea(unsigned char x0, unsigned char y0, unsigned char w, unsigned char h, unsigned char color)
{
    short i;
    unsigned char w0 = w / 2, x1 = x0 / 2, color0 = (color << 4) | color;
    unsigned char LCD_Temp[w0];

    for (i = 0; i < w0; i++) LCD_Temp[i] = color0;

    OLED_WR_CMD(0X15);
    OLED_WR_CMD(80 - x1 - w0);
    OLED_WR_CMD(80 - x1 - 1);

    OLED_WR_CMD(0x75);
    OLED_WR_CMD(64 - y0 - h);
    OLED_WR_CMD(64 - y0 - 1);

    OLED_WR_CMD(0xaf);
    OLED_WR_CMD(0xa1);
    OLED_WR_CMD(0x00);

    for (i = 0; i < h; i++) {
        OLED_WR_DAT_Plent(LCD_Temp, w0);
    }
}

void General_Pic_Display(unsigned char x0, unsigned char y0, unsigned char w, unsigned char h, char *pic, unsigned char color, unsigned char Bcolor)
{
    unsigned char x, y, temp, m, pic_ptr = 0, w0 = w / 2, x1 = x0 / 2;
    short k = (w + 7) / 8 * h - 1;

    color  = (color > 15) ? 15 : color;
    Bcolor = (Bcolor > 15) ? 15 : Bcolor;

    OLED_WR_CMD(0X15);
    OLED_WR_CMD(80 - x1 - w0);
    OLED_WR_CMD(80 - x1 - 1);
    OLED_WR_CMD(0x75);
    OLED_WR_CMD(64 - y0 - h);
    OLED_WR_CMD(64 - y0 - 1);
    OLED_WR_CMD(0xaf);
    OLED_WR_CMD(0xa1);
    OLED_WR_CMD(0x00);

    for (y = 0; y < h; y++) {
        x = 0;
        for (m = 0; m < w0; x++, m++) {
            if (x % 4 == 0) {
                pic_ptr = pic[k--];
            }
            temp = ((pic_ptr & 0x01) ? (color << 4) : (Bcolor << 4)) |
                   ((pic_ptr & 0x02) ? color : Bcolor);
            pic_ptr >>= 2;
            OLED_WR_DAT(temp);
        }
    }
}

void OLED_Clear_Screen(unsigned char color)
{
    OLED_FillArea(0, 0, 160, 64, color);
}
void OLED_Init(void)
{
    for (int i = 0; i < OLED_InitCMD[0]; i++) {
        OLED_WR_CMD(OLED_InitCMD[i]);
    }
    OLED_Clear_Screen(0x00);
    OLED_WR_CMD(0xaf);
}
